<?php
/***********************************************************************
 * @package     IvanEngine
 * @subpackage  Core
 * @author      Ivan <ivanzx@msn.com>
 * @created     2010-06-06
 ***********************************************************************/
if(defined("IVANENGINE_CORE_FILEHELPER"))
    die("Redefinition macro in :".__FILE__."(".__LINE__.")");
define("IVANENGINE_CORE_FILEHELPER", true);

require_once (dirname(__FILE__).'/../Common.php');
require_once (dirname(__FILE__).'/../Finder.php');

class CFileHelper extends CBase
{
    public function __construct()
    {
        parent::__construct();
    }
    
    public function __destruct()
    {
        parent::__destruct();
    }
    
    static public function IsExsit($fileName)
    {
        return file_exists($fileName);
    }
    
    static public function IsReadable($fileName)
    {
        return is_readable($fileName);
    }
    
    static public function IsWritable($fileName)
    {
        return is_writable($fileName);
    }
    
    // flag: FILE_APPEND
    static public function Write($fileName, $data, $flag = null, $throwMsg = true)
    {
        $result = @file_put_contents($fileName, $data, $flag);
        if( $throwMsg && $result === FALSE ){
            throw new CExceptionInvalidArgument("Can not write the file:<br>".$fileName);
        }
        return $result;
    }
    
    static public function Read($fileName, $throwMsg = true)
    {
        $fileContent = @file_get_contents($fileName);
        if( $throwMsg && $fileContent === FALSE ){
            throw new CExceptionInvalidArgument("Can not found out or read the file:<br>".$fileName);
        }
        return $fileContent;
    }
    
    static public function FileSize($fileName, $throwMsg = true)
    {
        $fileSize = @filesize($fileName);
        if( $throwMsg && $fileContent === FALSE ){
            throw new CExceptionInvalidArgument("Can not found out or read the file:<br>".$fileName);
        }
        return $fileSize;
    } 
    
    static public function CreateFile($fileName)
    {
        self::CreateDir(self::GetDirFromPath($fileName));
        
        if( !self::IsExsit($fileName) )
        {
            $f = @fopen($fileName, 'w');
            if(!$f){
                $f = fopen($fileName, 'w');
            }
            fclose($f); 
        }
        if(self::IsWritable($fileName)){
            return true;
        }else{
            return false;
        }
    }
    
    static public function CopyFile($srcFile, $descFile)
    {
        return copy($srcFile, $descFile);
    }
    
    static public function Rename($fileName, $newName)
    {
        return rename($fileName, $newName);
    }
    
    static public function DeleteFile($fileName)
    {
        return unlink($fileName);
    }
    
    static public function CreateDir($dir)
    {
        if(!is_dir($dir))
        {
            if(!self::CreateDir(dirname($dir))){
                return false;
            }
            // 0777 is admin access
            if(!mkdir($dir, 0777)){
                return false;
            }
        }
        return true;
    }
    
    static public function DeleteDir($fullPath)
    {
        return rmdir($fullPath);
    }
    
    static public function GetDirFromPath($fullPath)
    {
        return dirname($fullPath);
    }
    
    static public function GetFileFromPath($fullPath)
    {
        return basename($fullPath);
    }
    
    static public function GetCreateTime($fileName, $format='Y-m-d H:i:s')
    {
        $tmp = filectime($fileName);
        return date($format, $tmp);
    }
    
    static public function GetModifyTime($fileName, $format='Y-m-d H:i:s')
    {
        $tmp = filemtime($fileName);
        return date($format, $tmp);
    }
    
    static public function FindFile($path, $regex, $hasSubPath = true)
    {
        $files  = CFinder::Create(CFinder::FT_File)->AddRule($regex)->Go($path);
        $vector = new CVector();
        foreach( $files as $file )
        {
            if( self::IsAbsolutePath($file) ){
                $file = self::AbsoluteToRelativePath($file);
                if( $file ){
                    $vector->Add($file);
                }
            }else if ( is_string($file) ){
                $vector->Add($file);
            }else if( is_array($file) ){
                foreach( $file as $tmp ){
                    if( is_string($tmp)){
                        $vector->Add($tmp);
                    }
                }
            }
        }
        return $vector;
    }
    
    static public function CorrectDS($path)
    {
        if( M_DS === '\\' )
            $path = str_replace('/', M_DS, $path);
        else
            $path = str_replace('\\', M_DS, $path);
        return $path;
    }
    
    static public function AbsoluteToRelativePath($absolutePath, $rootPath = null)
    {
        $absolutePath   = self::CorrectPath($absolutePath);
        if( !self::IsAbsolutePath($absolutePath) )
            return $absolutePath;
        
        if( $rootPath ){
            $curPageAbsPath = self::CorrectPath($rootPath);
        }else{
            $curPageAbsPath = M_DOC_DIR;
        }
        $tempString     = substr($absolutePath, 0, strlen($curPageAbsPath));
        if( $curPageAbsPath == $tempString ){
            return substr($absolutePath, strlen($curPageAbsPath));
        }
        return $absolutePath;
    }
    
    static public function AToR($absolutePath, $rootPath = null)
    {
        return self::AbsoluteToRelativePath($absolutePath, $rootPath);
    }
    
    static public function CatDS($path)
    {
        if( $path[strlen($path)-1] != M_DS ){
            return $path.M_DS;
        }
        return $path;
    }
    
    static public function IsAbsolutePath($path)
    {
        if ($path{0} == '/' || $path{0} == '\\' ||
            (strlen($path) > 3 && ctype_alpha($path{0}) &&
            $path{1} == ':' && ($path{2} == '\\' || $path{2} == '/')))
        {
              return true;
        }
    
        return false;
    }
    
    static public function CorrectPath($path)
    {
        $path   = self::CorrectDS($path);
        $path   = self::_CorrectMultiDS($path);
        $path   = self::_CorrectParentDir($path);

        return $path;
    }
    
    static protected function _CorrectParentDir($dirStr)
    {
        $pos    = strpos($dirStr, '..');
        if( $pos !== FALSE )
        {
            $str    = CString::From(substr($dirStr, 0, $pos));
            $pos1   = $str->FindLastOf(M_DS);
            if( $pos1 != CString::npos )
            {
                $result = $str->SubStr(0, $pos1).substr($dirStr, $pos + 2);
                return self::_CorrectParentDir($result);
            }
        }
        return $dirStr;
    }
    
    static protected function _CorrectMultiDS($path)
    {
        $pos    = strpos($path, M_DS.M_DS);
        if( $pos !== FALSE )
        {
            $path = str_replace(M_DS.M_DS, M_DS, $path);
            $path = self::_CorrectMultiDS($path);
        }
        return $path;
    }
}
class HFile extends CFileHelper{}
?>
